package 蚂蚁课堂;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 读写锁：ReentrantReadWriteLock
 * 读-读是不加锁的可以并发执行
 * 读-写是加锁的，互斥的
 */
@Slf4j
public class ReentrantReadWriteLockDemo1 {

    private static String str="你好";
    //实例化一个读写锁
    private static ReentrantReadWriteLock rrwl=new ReentrantReadWriteLock();
    //实例化读锁
    private static ReentrantReadWriteLock.ReadLock readLock=rrwl.readLock();
    //实例化写锁
    private static ReentrantReadWriteLock.WriteLock writeLock=rrwl.writeLock();

    public static void main(String[] args) throws InterruptedException {

        new Thread(()->read()).start();
        //演示读写锁互斥，让读锁先创建成功，并开始读取数据，中间sleep了8秒。
        //1秒之后写锁创建成功，由于读锁获取了当前锁，那么写锁需要等待8秒之后读锁将锁释放，才能写成功
        TimeUnit.SECONDS.sleep(1);
        new Thread(()->write()).start();
    }

    /**
     * 读取数据
     * @return
     */
    public static String read(){
        log.info("获取读锁");
        //获取读锁
        readLock.lock();

        try {
            log.info("开始读取数据");
            TimeUnit.SECONDS.sleep(8);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            log.info("释放读锁");
            readLock.unlock();
        }
        return str;
    }

    public static void write(){
        writeLock.lock();
        log.info("写入数据");
    }
}
